package com.kk.my_pro.common.utility.jwt;

import com.alibaba.fastjson.JSONObject;
import com.kk.my_pro.common.result.ApiResult;
import com.kk.my_pro.common.utility.thread.RequestInfo;
import com.kk.my_pro.config.security.DBUserDetailsManager;
import com.kk.my_pro.entity.User;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

import static com.kk.my_pro.config.security.WebSecurityConfig.ALLOW_PATH_PATTERNS;

/**
 * 自定义过滤器
 */

@Component
@Slf4j
public class JwtFilter extends OncePerRequestFilter {


    private final static Map<String, List<String>> ROLE_AUTHORIZATION = new HashMap<>(); // 用户权限设置  后期写入数据库

    static {
        ROLE_AUTHORIZATION.put("user", List.of("/systemUser/check2","/systemUser/check"));
        ROLE_AUTHORIZATION.put("admin", List.of("/systemUser/XXXX"));
    }


    @Autowired
    JwtUtil jwtUtil;

    @Resource
    DBUserDetailsManager userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {


        // 获取请求的完整路径
        String requestURI = request.getRequestURI();

        // 获取请求的Servlet路径
        String servletPath = request.getServletPath();

        // 获取请求的上下文路径
        String contextPath = request.getContextPath();

        // 获取请求的路径信息（不包括查询参数）
        String pathInfo = request.getPathInfo();

        // 获取请求的查询字符串
        String queryString = request.getQueryString();


        String jwtToken = request.getHeader("token");//从请求头中获取token
        if (jwtToken != null && !jwtToken.isEmpty() && jwtUtil.checkToken(jwtToken)) { //jwtUtil.checkToken(jwtToken)校验登录是否合法
            try {//token可用
                Claims claims = jwtUtil.getTokenBody(jwtToken);
                String userName = (String) claims.get("userName");
                UserDetails user = userService.loadUserByUsername(userName); //工具用户名查询数据库
                if (user != null) {
                    UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(auth); // 类似将用户等信息放在一个threadLocal

                    String role = user.getAuthorities().stream().map(e -> e.getAuthority()).toList().get(0);//获取本次登录用户的角色
                    boolean containsRole = ROLE_AUTHORIZATION.keySet().contains(role); // 判断系统是否包含本次登录用户的角色
                    if (containsRole) {
                        for (Map.Entry<String, List<String>> entry : ROLE_AUTHORIZATION.entrySet()) {
                            if (role.equals(entry.getKey())) {
                                //判断本次登录的角色是否有权限访问本次的请求路径
                                boolean contains = entry.getValue().contains(servletPath);
                                if (!contains) {
                                    //如果没有权限
                                    response.setContentType("application/json;charset=UTF-8");
                                    response.setCharacterEncoding("UTF-8");
                                    String json = JSONObject.toJSONString(ApiResult.failure("访问权限不足！"));
                                    PrintWriter writer = response.getWriter();
                                    writer.write(json);
                                    writer.close();
                                    log.warn("访问权限不足！");
                                    return;
                                }else {
                                    // 登录成功
                                    RequestInfo.set(RequestInfo.builder()
                                            .user((User)user)
                                            .build());
                                    log.warn("登录成功！");
                                }

                            }

                        }
                    } else {
                        response.setContentType("application/json;charset=UTF-8");
                        response.setCharacterEncoding("UTF-8");
                        String json = JSONObject.toJSONString(ApiResult.failure("系统不存在该角色！"));
                        PrintWriter writer = response.getWriter();
                        writer.write(json);
                        writer.close();
                        log.warn("系统不存在该角色！");
                        return;
                    }

                }
            } catch (Exception e) {

                log.error(e.getMessage());
            }
        } else {

            if(!Arrays.asList(ALLOW_PATH_PATTERNS).contains(servletPath)){
                //判断本次请求是否是登录接口，如果是则无需拦截
                response.setContentType("application/json;charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
                String json = JSONObject.toJSONString(ApiResult.failure("token不合法！"));
                PrintWriter writer = response.getWriter();
                writer.write(json);
                writer.close();
                log.warn("token不合法！");
                return;
            }


        }
        filterChain.doFilter(request, response);//继续过滤
    }
}